/*
	*@brief				：自旋锁的初始化，加锁与解锁

	*@param[lock]		: lock 指向了需要进行初始化或销毁的自旋锁对象
	*@param[pshared]	:PTHREAD_PROCESS_SHARED： 共享自旋锁。该自旋锁可以在多个进程中的线程之间共享；
						 PTHREAD_PROCESS_PRIVATE： 私有自旋锁。只有本进程内的线程才能够使用该自旋锁。

	*@param[attr]		:可将参数 attr 设置为 NULL，表示使用属性的默认值来初始化条件变量，与使用 PTHREAD_COND_INITIALIZER 宏相同。

	*@return 			:成功返回 0；失败将返回一个非 0 的错误码。
	*@others			:如果自旋锁处于未锁定状态，调用 pthread_spin_lock()会将其锁定（上锁），如果其它线程已经将自旋锁锁住了，那本次调用将会“自旋”等待；如果试图对同一自旋锁加锁两次必然会导致死锁。
*/

/*
	int pthread_spin_destroy(pthread_spinlock_t *lock);
	int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
	int pthread_spin_lock(pthread_spinlock_t *lock);
	int pthread_spin_trylock(pthread_spinlock_t *lock);
	int pthread_spin_unlock(pthread_spinlock_t *lock);
*/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

static pthread_spinlock_t spin; //定义自旋锁
static int g_count = 0;

static void *new_thread_start(void *arg)
{
	int loops = *((int *)arg);
	int l_count, j;
	
	for (j = 0; j < loops; j++)
	{
		pthread_spin_lock(&spin); //自旋锁上锁
		l_count = g_count;
		l_count++;
		g_count = l_count;
		pthread_spin_unlock(&spin); //自旋锁解锁
	}
	return (void *)0;
}

static int loops;

int main(int argc, char *argv[])
{
	pthread_t tid1, tid2;
	int ret;

	/* 获取用户传递的参数 */
	if (2 > argc)
		loops = 10000000; //没有传递参数默认为 1000 万次
	else
		loops = atoi(argv[1]);

	/* 初始化自旋锁(私有) */
	pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE);

	/* 创建 2 个新线程 */
	ret = pthread_create(&tid1, NULL, new_thread_start, &loops);
	if (ret)
	{
		fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
		exit(-1);
	}

	ret = pthread_create(&tid2, NULL, new_thread_start, &loops);
	if (ret)
	{
		fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
		exit(-1);
	}

	/* 等待线程结束 */
	ret = pthread_join(tid1, NULL);
	if (ret)
	{
		fprintf(stderr, "pthread_join error: %s\n", strerror(ret));
		exit(-1);
	}

	ret = pthread_join(tid2, NULL);
	if (ret)
	{
		fprintf(stderr, "pthread_join error: %s\n", strerror(ret));
		exit(-1);
	}
	/* 打印结果 */

	printf("g_count = %d\n", g_count);
	/* 销毁自旋锁 */
	pthread_spin_destroy(&spin);
	exit(0);
}